<?php

namespace App\Http\Controllers\Api;

use App\Events\SendNoticeToOne;
use App\Http\Requests\Api\DealBuyRequest;
use App\Http\Requests\Api\DealRequest;
use App\Models\Deal;
use App\Models\DealBuyer;
use App\Models\DealLine;
use App\Models\DealLog;
use App\Models\EDealLog;
use App\Models\Recharge;
use App\Models\User;
use App\Models\Wallet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

/**
 * @title 交易
 * @description 接口说明
 * @header name:accessToken require:1 default: desc:用户accessToken
 */
class TradeController extends ApiController
{
    /**
     * @title 卖出页面
     * @description 接口说明
     * @author wjx
     * @url /api/trade/sellPage
     * @method POST
     *
     * @return nickname:昵称
     * @return amount:持有数量
     */
    public function sellPage(Request $request)
    {
        $user = $request->user;
        $data = [];
        $data['nickname'] = $user->nickname;
        $data['amount'] = $user->wallet->tmc;
        return $this->success($data);
    }
    /**
     * @title 卖出确认
     * @description 接口说明
     * @author wjx
     * @url /api/trade/sellTmc
     * @method POST
     * @param name:price type:float require:1  other: desc:卖出单价
     * @param name:num type:int require:1  other: desc:卖出数量
     * @param name:total_price type:int require:1  other: desc:总计收入
     * @param name:security type:string require: default:1 other: desc:交易密码
     */
    public function sellTmc(Request $request, DealRequest $dealrequest, DealLine $deal_line)
    {
        $user = $request->user;
        $tmc = $user->wallet->tmc;
        $sell_price = $dealrequest->price;
        if ($dealrequest->num == 0) {
            return $this->failed('数量有误');
        }
        if ($dealrequest->num > $tmc) {
            return $this->failed('你可卖出的E格码数量为' . $tmc . '个');
        }

        $today_price = $deal_line->orderBy('id', 'desc')->value('price');
        if ($sell_price < ($today_price * 0.9) || $sell_price > ($today_price * 1.1)) {
            return $this->failed("建议卖出价格在 " . $today_price * 0.9 . "--" . $today_price * 1.1 . " 之间");
        }

        if (!Hash::check($dealrequest->security, $user->security)) {
            return $this->failed('交易密码错误');
        }
        $deal = new Deal();
        $deal->user_id = $user->id;
        $deal->price = $sell_price;
        $deal->total_amount = $dealrequest->num;
        $deal->rest_amount = $dealrequest->num;
        $deal->total_price = $dealrequest->total_price;
        $deal->status = 1;
        $wallet = $user->wallet;
        $wallet->tmc = bcsub($tmc, $dealrequest->num, 4);
        DB::beginTransaction();
        try {
            $deal->save();
            $wallet->save();

            DB::commit();
            return $this->message('售卖成功');
        } catch (\Exception $exception) {
            // dd($exception->getMessage());
            DB::rollBack();
            return $this->failed('售卖失败');
        }

    }

    /**
     * @title 挂卖列表
     * @description 接口说明
     * @author wjx
     * @url /api/trade/dealList
     * @method POST
     *
     * @param name:order_by type:int require: default:3  other: desc:排序方式1价格2数量3时间
     * @param name:type type:string require:1 default:refresh other: desc:方法参数:more/refresh
     * @param name:offset type:int require:1 default:10 other: desc:方法参数:每页数据量
     * @param name:ID type:int require:1 default:-1 other: desc:数据起点ID
     * @return deal_list:数据@
     * @deal_list deal_id:记录id seller_id:挂卖者id avatar:用户头像 unit_price:单价 total_amount:出售数量 rest_amount:剩余数量
     */
    public function dealList(Request $request)
    {
        $user = $request->user;
        $order_by = $request->order_by;
        switch ($order_by) {
            case '1':
                $order = 'price';
                $sort = 'asc';
                break;
            case '2':
                $order = 'rest_amount';
                $sort = 'desc';
                break;
            case '3':
                $order = 'id';
                $sort = 'desc';
                break;
            default:
                $order = 'id';
                $sort = 'desc';
                break;
        }
        $startId = $request->ID ? $request->ID : 0;
        $offset = $request->offset ? $request->offset : 10;
        if ($offset > 25) {
            $offset = 25;
        }
        $loadType = $request->type;
        if (!in_array($loadType, ['more', 'refresh'])) {
            return $this->failed('type参数错误');
        }

        if ($loadType == 'more') {
            $deal_list = Deal::filters([['status', '=',1], ['is_deleted', '=',0], ['rest_amount', '<>', 0],['id', '<', $startId]])
            ->orderBy($order, $sort)
            ->with('user')
            ->take($offset)
            ->get();
        } else {
            $deal_list = Deal::filters([['status','=', 1], ['is_deleted','=', 0], ['rest_amount', '<>', 0],['id', '>', $startId]])
            ->orderBy($order, $sort)
            ->with('user')
            ->take($offset)
            ->get();
        }

        

        $deal_list->transform(function ($item) {
            $item->deal_id = $item->id;
            $item->seller_id = $item->user_id;
            $item->avatar = $item->user->avatar;
            $item->unit_price = $item->price;
            return $item->only(['id','deal_id', 'seller_id', 'avatar', 'unit_price', 'total_amount', 'rest_amount']);
        });

        return $this->success(compact('deal_list'));
    }

    /**
     * @title 我的卖出
     * @description 接口说明
     * @author wjx
     * @url /api/trade/mySellList
     * @method POST
     * @param name:type type:string require:1 default:refresh other: desc:方法参数:more/refresh
     * @param name:offset type:int require:1 default:10 other: desc:方法参数:每页数据量
     * @param name:ID type:int require:1 default:-1 other: desc:数据起点ID
     * @return sell_lists:数据@
     * @sell_lists deal_id:交易ID total_price:总计 unit_price:单价 rest_amount:剩余数量 total_amount:出售数量  status:状态(1进行中/2已取消/3已完成)  created_at:时间
     */
    public function mySellList(Request $request)
    {
        $user = $request->user;
        $startId = $request->ID ? $request->ID : 0;
        $offset = $request->offset ? $request->offset : 10;
        if ($offset > 25) {
            $offset = 25;
        }
        $loadType = $request->type;
        if (!in_array($loadType, ['more', 'refresh'])) {
            return $this->failed('type参数错误');
        }

        if ($loadType == 'more') {
            $sell_lists = Deal::filters([
                ['user_id','=',$user->id],
                ['id', '<', $startId],
            ])
            ->with('user')
            ->take($offset)
            ->orderBy('id', 'desc')
            ->get();
        } else {
            $sell_lists = Deal::filters([
                ['user_id','=',$user->id],
                ['id', '>', $startId],
            ])
            ->with('user')
            ->take($offset)
            ->orderBy('id', 'desc')
            ->get();
        }

        $sell_lists->transform(function ($item) {
            $item->deal_id = $item->id;
            $item->unit_price = $item->price;

            return [
                'id' => $item->id,
                'deal_id' => $item->deal_id,
                'total_price' => $item->total_price,
                'unit_price' => $item->unit_price,
                'rest_amount' => $item->rest_amount,
                'total_amount' => $item->total_amount,
                'status' => $item->status,
                'created_at' => $item->created_at->toDateTimeString(),
            ];
        });
        return $this->success(compact('sell_lists'));
    }
    /**
     * @title 我的买入
     * @description 接口说明
     * @author wjx
     * @url /api/trade/myBuyList
     *
     * @method POST
     * @param name:type type:string require:1 default:refresh other: desc:方法参数:more/refresh
     * @param name:offset type:int require:1 default:10 other: desc:方法参数:每页数据量
     * @param name:ID type:int require:1 default:-1 other: desc:数据起点ID
     * @return buy_lists:数据@
     * @buy_lists deal_id:交易ID total_price:总计 unit_price:单价 total_amount:购买数量 trade_status:状态(已完成) created_at:时间
     */
    public function myBuyList(Request $request)
    {
        $user = $request->user;
        $startId = $request->ID ? $request->ID : 0;
        $offset = $request->offset ? $request->offset : 10;
        if ($offset > 25) {
            $offset = 25;
        }
        $loadType = $request->type;
        if (!in_array($loadType, ['more', 'refresh'])) {
            return $this->failed('type参数错误');
        }

        if ($loadType == 'more') {
            $buy_lists = DealBuyer::filters([['user_id','=',$user->id], ['is_deleted','=',0],['id','<',$startId]])
                        ->with('user')
                        ->take($offset)
                        ->orderBy('id', 'desc')
                        ->get();
        } else {
            $buy_lists = DealBuyer::filters([['user_id','=',$user->id], ['is_deleted','=',0],['id','>',$startId]])
                        ->with('user')
                        ->take($offset)
                        ->orderBy('id', 'desc')
                        ->get();
        }
        
        $buy_lists->transform(function ($item) {
            $item->deal_id = $item->id;
            $item->unit_price = $item->price;
            return [
                'id' => $item->id,
                'deal_id' => $item->deal_id,
                'total_price' => $item->total_price,
                'unit_price' => $item->unit_price,
                'rest_amount' => $item->rest_amount,
                'total_amount' => $item->total_amount,
                'status' => $item->status,
                'created_at' => $item->created_at->toDateTimeString(),
            ];
        });
        return $this->success(compact('buy_lists'));
    }
    /**
     * @title 买入页面
     * @description 接口说明
     * @author wjx
     * @url /api/trade/buyPage
     * @method POST
     * @param name:deal_id type:int require:1 default:1 other: desc:记录ID
     *
     * @return deal_id:交易ID
     * @return nickname:昵称
     * @return rest_amount:剩余数量
     * @return price:买入价格
     */
    public function buyPage(Request $request)
    {
        $deal_id = $request->deal_id;
        if (!$deal_id) {
            return $this->failed('缺少参数deal_id');
        }

        $deal = Deal::where('id', $deal_id)->with('user')->first();
        if($deal->status == 2){
            return $this->failed('该挂卖已取消');
        }
        $data = [];

        $data['deal_id'] = $deal_id;
        $data['nickname'] = $deal->user->nickname;
        $data['rest_amount'] = $deal->rest_amount;
        $data['price'] = $deal->price;
        return $this->success($data);
    }
    /**
     * @title 买入确认
     * @description 接口说明
     * @author wjx
     * @url /api/trade/buyTmc
     * @method POST
     * @param name:deal_id type:int require:1 default:1 other: desc:记录ID
     * @param name:total_amount type:int require:1 default:1 other: desc:购买数量
     * @param name:total_price type:int require:1 default:1 other: desc:购买总价
     * @param name:pay_type type:int require:1 default:1 other: desc:1微信2余额
     * @param name:security type:string require: default:1 other: desc:交易密码
     *
     * @return param:调起微信所需参数
     */
    public function buyTmc(Request $request, DealBuyRequest $buyrequest)
    {
        $user = $request->user;

        $wallet = $user->wallet;
        $deal_id = $buyrequest->deal_id;
        $total_amount = $buyrequest->total_amount;
        $total_price = $buyrequest->total_price;
        $pay_type = $buyrequest->pay_type;
        $check_pass = Hash::check($buyrequest->security, $user->security);

        $deal = Deal::where('id', $deal_id)->with('user')->first();
        if ($deal->user_id == $user->id) {
            return $this->failed('不能购买自己的挂卖');
        }
        if ($deal->rest_amount < $total_amount) {
            return $this->failed('剩余数量不足，请刷新后重新输入');
        }
        if($deal->status == 2){
            return $this->failed('该挂卖已取消');
        }
        if ($pay_type == 2) { //余额支付
            if ($check_pass == false) {
                return $this->failed('交易密码错误');
            }
            if ($wallet->money < $buyrequest->total_price) {
                return $this->failed('余额不足，请充值');
            }

            $seller_wallet = Wallet::where('user_id', $deal->user_id)->first();
            $deal->rest_amount = bcsub($deal->rest_amount, $total_amount, 4);

            $deal_buy = new DealBuyer();
            $deal_buy->user_id = $user->id;
            $deal_buy->deal_id = $deal_id;
            $deal_buy->pay_type = 2;
            $deal_buy->pay_at = date('Y-m-d H:i:s');
            $deal_buy->out_trade_no = set_order_no();
            $deal_buy->price = $deal->price;
            $deal_buy->total_amount = $total_amount;
            $deal_buy->total_price = $total_price;
            $deal_buy->status = 3;

            $wallet->money = bcsub($wallet->money, $total_price, 2);
            $wallet->tmc = bcadd($wallet->tmc, $total_amount, 4);

            $seller_wallet->money = bcadd($seller_wallet->money, $total_price, 2);
            DB::beginTransaction();
            try {
                $deal->save();
                if ($deal->rest_amount == 0) {
                    $deal->status = 3;
                    $deal->save();
                }
                $deal_buy->save();
                $wallet->save();
                $seller_wallet->save();
                DealLog::add_log($user->id, $deal->user_id, $total_price, 2, '购买E格码消耗(余额)');
                DealLog::add_log($deal->user_id, $user->id, $total_price, 1, '卖出E格码增加(余额)');
                EDealLog::add_log($user->id, $deal->user_id, $total_amount, 1, '买入E格码增加', 0);
                EDealLog::add_log($deal->user_id, $user->id, $total_amount, 2, '卖出E格码减少', 0);
                DB::commit();
                event(new SendNoticeToOne($deal_buy,2,11));
                return $this->message('购买成功');
            } catch (\Exception $exception) {
                dd($exception->getMessage());
                DB::rollBack();
                return $this->failed('购买失败');
            }
        } else { //微信支付
            $deal_buy = new DealBuyer();
            $deal_buy->user_id = $user->id;
            $deal_buy->deal_id = $deal_id;
            $deal_buy->pay_type = 1;
            $deal_buy->out_trade_no = set_order_no();
            $deal_buy->price = $deal->price;
            $deal_buy->total_amount = $total_amount;
            $deal_buy->total_price = $total_price;
            $deal_buy->status = 1;
            $deal_buy->save();

            $recharge = new Recharge();
            $recharge->user_id = $user->id;
            $recharge->money = $total_price;
            $recharge->type = 6; //充值购买e币
            $recharge->pay_type = 1; //默认微信
            $recharge->status = 1; //未成功付款
            $recharge->out_trade_no = $deal_buy->out_trade_no;
            $recharge->save();

            $pay = app('wechat_pay')->app([
                'out_trade_no' => $recharge->out_trade_no, // 商户订单流水号，与支付宝 out_trade_no 一样
                // 'total_fee' => $total_price*100, // 与支付宝不同，微信支付的金额单位是分。
                'total_fee' => 1, // 与支付宝不同，微信支付的金额单位是分。
                'body' => '购买E格币', // 订单描述
            ]);
            
            return $this->success(json_decode($pay->getContent()));
        }

    }

    /**
     * @title 删除订单页面
     * @description 接口说明
     * @author wjx
     * @url /api/trade/delTradePage
     * @method POST
     */
    public function delTradePage(Request $request)
    {
        $user = $request->user;

        $sell_lists = Deal::where(['user_id' => $user->id, 'status' => 1, 'is_deleted' => 0])
            ->whereColumn('total_amount', 'rest_amount')
            ->with('user')
            ->get();
        $new_lists = [];
        foreach ($sell_lists as $key => $value) {
            $new_lists[$key] = $value->transform_deal();
        }
        return $this->success($new_lists);
    }
    /**
     * @title 删除订单确认
     * @description 接口说明
     * @author wjx
     * @url /api/trade/delTrade
     * @method POST
     * @param name:deal_id type:int require:1 default:1 other: desc:交易ID(数组)
     */
    public function delTrade(Request $request)
    {
        $user = $request->user;
        $wallet = $user->wallet;
        $deal_id = $request->deal_id;
        if (!is_array($deal_id)) {
            return $this->failed('参数deal_id错误');
        }
        $deal = Deal::where(['user_id' => $user->id])
            ->whereIn('id', $deal_id)
            ->whereColumn('total_amount', 'rest_amount')
            ->get();
        if (count($deal) == 0) {
            return $this->failed('订单不存在');
        }
        $total_amount = $deal->sum('total_amount');
        // $deal->is_delete = 1;

        $wallet->tmc = bcadd($wallet->tmc, $total_amount, 4);
        DB::beginTransaction();
        try {
            Deal::where(['user_id' => $user->id])
                ->whereIn('id', $deal_id)
                ->whereColumn('total_amount', 'rest_amount')
                ->update(['is_deleted' => 1,'status'=>2]);
            $wallet->save();
            DB::commit();
            event(new SendNoticeToOne($user,2,10));
            return $this->message('删除成功');
        } catch (\Exception $exception) {
            // dd($exception->getMessage());
            DB::rollBack();
            return $this->failed('删除失败');
        }
    }

    /**
     * @title 行情
     * @description 接口说明
     * @author wjx
     * @url /api/trade/dealLine
     * @method POST
     *
     * @return had_cre:总产出
     * @return yes_cre:昨日产出
     * @return my_cre:我的产出
     * @return today_price:今日价格
     * @return deal_line:  @
     * @deal_line date:日期 deal_price:价格
     */
    public function dealLine(Request $request, DealLine $deal_line)
    {
        $user = $request->user;
        $had_cre = $deal_line->orderBy('id', 'desc')->value('total_e');
        $start_time = date("Y-m-d");
        // $yes_time = date("Y-m-d", strtotime("-1 day"));
        $yes_cre = EDealLog::where('type', 1)->whereDate('created_at', $start_time)->sum('money');
        $my_cre = EDealLog::where(['type' => 1, 'user_id' => $user->id])->sum('money');
        $today_price = $deal_line->orderBy('id', 'desc')->value('price');

        $lists = $deal_line
            ->orderBy('id', 'desc')
            ->limit(7)
            ->get(['date', 'deal_price'])->toArray();

        krsort($lists);
        $deal_line = array_column($lists, null);

        return $this->success(compact('had_cre', 'yes_cre', 'my_cre', 'today_price', 'deal_line'));
    }

}
